import re,os,sys
def read_file(filename):
    try:
        try:
            try:
                with open(filename,'r',encoding='utf-8') as r:
                    lines=r.readlines()
            except:
                with open(filename, 'r', encoding='gbk') as r:
                    lines = r.readlines()
        except:
            with open(filename, 'r', encoding='utf-16') as r:
                lines = r.readlines()
    except:
        with open(filename, 'r', encoding='GB2312') as r:
            lines = r.readlines()
    return lines
import re,os

vowel = [ 'ie', 'au', 'eu', 'äu', 'ei', 'ai', 'ey', 'ay', 'er', # 双元音
          'aa', 'ee', 'ii', 'oo', 'uu', 'ää', 'öö', 'üü',
          'a', 'e', 'i', 'o', 'u', 'ä', 'ö', 'ü',] # 单元音
# 辅音
consonant = ['tzsch', 'dsch', 'tsch', 'zsch', 'chs', 'sch', 'ch', 'ck', 'dt','nk', 'pf', 'ph', 'qu', 'ss', 'th','ng',
              'ti','tz', 'b', 'c', 'd', 'f', 'g', 'h', 'j', 'k', 'l', 'm', 'n', 'p', 'r', 's', 'ß', 't', 'v', 'w', 'x', 'y', 'z']
subffix=['dazwischen', 'weiter', 'wieder', 'hinein', 'zurück', 'wider', 'durch', 'unter', 'dazu', 'frei', 'voll', 'nach', 'miss', 'aus', 'auf', 'bei', 'ein', 'mit', 'vor', 'ent','emp', 'ver', 'zer', 'zu', 'um', 'er', 'be', 'ge']
# 双辅音发音为单辅音，替换重复辅音
# def getnewstr(str):
#     newstr=[]
#     for s in str:
#         if len(newstr)<1:
#             newstr.append(s)
#             continue
#         elif newstr[-1]==s:
#             continue
#         newstr.append(s)
#     return ''.join(newstr)
def get_newstr(str1):
    str1=list(str1)
    newstr=[]
    for i in range(len(str1)):
        if i<len(str1)-1:
            if str1[i] in consonant:
              if str1[i+1]==str1[i]:
                 pass
              else:
                  newstr.append(str1[i])
            else:
                newstr.append(str1[i])
        else:
            newstr.append(str1[i])
    return ''.join(newstr)
def get_elemento_one_hot(word_list):
    '''vowel = ['uai', 'uei', 'uiu', 'uão', 'uem', 'uõe',  # 三重元音
             'ai', 'au', 'ei', 'éi', 'eu', 'éu', 'iu', 'oi', 'ói', 'ou', 'ui', 'am',
             'an', 'em', 'en', 'im', 'in', 'om', 'on', 'um', 'un', 'ão', 'ãe', 'õe',  # 二重元音
             'a', 'e', 'i', 'o', 'u', 'á', 'ã', 'à', 'â', 'é', 'ê', 'è', 'í', 'õ', 'ó', 'ô', 'û', 'ù', 'ú']  # 单元音'''

    # 使用0/1将代替元音和辅音
    syllable_one_hot=[]
    for word in word_list:
        word=get_newstr(word)
        # word=getnewstr(word)
        temp_list=[] #元辅音标记
        temp_syllable=[]
        # 有无数字都同样执行下面的代码
        i = 0
        while i < len(word):
            if i==0:
                for se in range(10):
                    s=11-se
                    if word[i:i + s] in subffix:  #
                        temp_list.append(0)
                        temp_syllable.append(word[i:i + s])
                        i += s
                        continue
            if i<len(word):
                if word[i:i + 5] in consonant:  # 三重元音
                    temp_list.append(1)
                    temp_syllable.append(word[i:i +5])
                    i += 5
                    continue  # 跳出本次循环，继续下一个
                if word[i:i + 4] in consonant:  # 三重元音
                    temp_list.append(1)
                    temp_syllable.append(word[i:i + 4])
                    i += 4
                    continue  # 跳出本次循环，继续下一个
                if word[i:i + 3] in consonant:  # 三重元音
                    temp_list.append(1)
                    temp_syllable.append(word[i:i + 3])
                    i += 3
                    continue  # 跳出本次循环，继续下一个
                if word[i:i + 2] in consonant:  # 三重元音
                    temp_list.append(1)
                    temp_syllable.append(word[i:i + 2])
                    i += 2
                    continue  # 跳出本次循环，继续下一个
                elif word[i:i + 2] in vowel:  # 二重元音
                    temp_list.append(0)
                    temp_syllable.append(word[i:i + 2])
                    i += 2
                    continue  # 跳出本次循环，继续下一个

                elif word[i] in vowel:  # 单元音
                    temp_list.append(0)
                    temp_syllable.append(word[i])
                    i += 1
                    continue  # 跳出本次循环，继续下一个
                elif word[i] in consonant:  # 单辅音
                    temp_list.append(1)
                    temp_syllable.append(word[i])
                    i += 1
                    continue  # 跳出本次循环，继续下一个
                else:
                    # 其他特殊字符
                    i += 1
        syllable_one_hot.append((temp_syllable, temp_list))
        # 将含有数字的整个单词都忽略掉
    return syllable_one_hot
# 划分音节
def get_syllable(elemento_one_hot):
    add_local = []
    # syllable_list=[]#音节列表
    syllable_dic = {}
    n = 0
    flag1 = 1
    flag2 = 1
    for i in range(n, len(elemento_one_hot[1])):
        if i == 0:  # 开始的位置
            if elemento_one_hot[1][i] == 0:
                flag1 = 0  # 一开始为元音
                continue
            else:
                flag2 = 0
        # 一开始为元音
        if flag1 == 0:
            if elemento_one_hot[1][i] == 0:
                loc = i  # 两个元音连在一起添加标记
                if loc != 0:
                    add_local.append(loc)  # 在i的位置添加标记
                continue
            else:
                flag1 = 1  # 出现一个辅音
                continue
        if flag1 != 0:  # 出现辅音后再出现元音
            if elemento_one_hot[1][i] == 0:
                if i == 2:
                    if elemento_one_hot[1][i - 2] == 1 and elemento_one_hot[1][i - 1] == 1:
                        continue
                    elif elemento_one_hot[0][i - 2] in subffix:
                        loc = i - 1
                        if loc != 0:
                            add_local.append(loc)  # 在i的位置添加标记
                        flag1 = 0
                        n = i - 1
                        continue
                else:
                    if i == 3:
                        if elemento_one_hot[1][0] == 1 and elemento_one_hot[1][1] == 1 and elemento_one_hot[1][
                            2] == 0:
                            loc = i
                            if loc != 0:
                                add_local.append(loc)  # 在i的位置添加标记
                            flag1 = 0
                            n = i - 1
                            continue
                    loc = i - 1
                    if loc != 0:
                        add_local.append(loc)  # 在i的位置添加标记
                    flag1 = 0
                    n = i - 1
                    continue
        if flag2 == 0:  # 第一个为辅音，继续再次判断元音还是辅音
            if elemento_one_hot[1][i] == 1:
                continue
    # 添加分隔位置标记
    l = 0
    for loc in add_local:
        elemento_one_hot[0].insert(loc + l, '.')
        l += 1
    # syllable_dic[re.sub('\.', '', ''.join(elemento_one_hot[0]))] = elemento_one_hot[0]
    # print('222',''.join(elemento_one_hot[0]))
    return ''.join(elemento_one_hot[0])
# if __name__=='__main__':
#     line = 'Wetter.'
#     line = re.sub('[^\s\w-]', '', line).strip()
#     word_list = re.split('[\s]+', line.lower())  # 划分单词不以-划分
#     syllable_one_hot=get_elemento_one_hot(word_list)
#     print(syllable_one_hot)
#     for elemento_one_hot in syllable_one_hot:
#         syllable=get_syllable(elemento_one_hot)
#         print(syllable)



'''
# 音节检查规则：
两元音之间有一个辅音字母(或辅音组合)时,辅音字母归后一音节，
两元音之间有不止一个辅音字母(或辅音组合)时，通常最后一个辅音字母(或辅音组合)属于后一个音节
'''



def main(path):
    errodic={} #记录错误
    allrecord={} #分别记录每个文件中的错误
    alleledic={} #所有元素
    # 统计音素出现频次及覆盖率，音素列表，非法音素
    allword_dic={} # 单词一致性检查:即每个单词的发音如果大于2就报出来，
    vowel0=['á','ã','à','â','é','ê','è','ì','í','î''õ','ó','ò','ô','û','ù','ú', 'a','e','i','o','u']
    legal_w=[l.strip() for l in read_file('勿删/合法音素词典.txt')]
    #合法因素
    # legal_w = ['i', 'e', 'a', 's', 'u', 'z', 'd', 't', 'o', 'r', 'i', 'ɐ', 'p', 'k', 'r', 'm', 'n', 'i', 'u', 'dʒ', 'w', 'l', 'ɐ~', 'tʃ', 'j', 'v', 'e', 'g', 'f', 'u~', 'b', 'h', 'ɛ', 'ʒ', 'ɔ', 'u~', 'o~', 'a', 'ɲ', 'ʃ', 'ʎ', 'j~', 'e~', 'i~']
    for rt,_,files in os.walk(path):
        for file in files:
            fileerro={} #文本错误
            #句子首尾不能出现空格/tab
            recorddic1 = {}  # 出现多个重音符号
            recorddic2 = {}  # #重音标记错误
            recorddic3 = {}  # 缺少重读符号
            recorddic4 = {}  #连读符号报错
            recorddic5 = {}  # 多个空格
            spaceerro =  {}  #tab错误
            recorddic6 = {} #句末为/
            digiterro = {} #检查数字前面是不是有空格
            syl_erro  = {} #划分音节错误

            filename=os.path.join(rt,file)
            lines=read_file(filename)
            if len(lines) % 2 == 0:
                for i in range(0,len(lines),2):
                    splitline=lines[i].split('\t')  #文本行
                    splitrhline=lines[i+1].split('\t') #音标行
                    if len(splitline)<2:
                        if '文本tab键错误' not in spaceerro:
                            spaceerro['文本tab键错误']=["文本无tab键\n{}".format(lines[i])]
                    elif len(splitline)>2:
                        if '文本tab键错误' not in spaceerro:
                            spaceerro['文本tab键错误']=["文本有多个tab键\n{}".format(lines[i])]
                    if len(splitrhline)<2:
                        if '文本tab键错误' not in spaceerro:
                            spaceerro['文本tab键错误']=["音标无tab键\n{}".format(lines[i+1])]
                    elif len(splitrhline)>2:
                        if '文本tab键错误' not in spaceerro:
                            spaceerro['文本tab键错误']=["音标有多个tab键\n{}".format(lines[i+1])]
                    if len(splitrhline)==2 and len(splitline)==2:
                        sequence=splitline[0]
                        result5=re.findall('\s{2,}',splitline[1])
                        result6=re.findall('\s{2,}',splitrhline[1])
                        if result5!=[]:
                            if '多空格' not in recorddic5:
                                recorddic5['多空格']=[splitline[1]]
                            else:
                                recorddic5['多空格'].append(splitline[1])
                        if result6!=[]:
                            if '多空格' not in recorddic5:
                                recorddic5['多空格']=[splitrhline[1]]
                            else:
                                recorddic5['多空格'].append(splitrhline[1])
                        newsplitline=splitline[1].replace('\n','') #去掉音标行的\n
                        newsplitrhline= splitrhline[1].replace('\n','')
                        if len(newsplitline)>1:
                            if newsplitline[-1]=='/':
                                if '句末为"/"' not in recorddic6:
                                    recorddic6['句末为"/"']=[splitline[1]]
                                else:
                                    recorddic6['句末为"/"'].append(splitline[1])
                        if len(newsplitrhline)>1:
                            if newsplitrhline[-1]=='/':
                                if '句末为"/"' not in recorddic6:
                                    recorddic6['句末为"/"']=[splitrhline[1]]
                                else:
                                    recorddic6['句末为"/"'].append(splitrhline[1])
                        word_list=re.split('\s',newsplitline.lower()) #文本行的句子
                        rhword_list=re.split(' / ',newsplitrhline) #音标行
                        if len(word_list)==len(rhword_list):
                            # 重读音节错误
                            for index, syl_word in enumerate(rhword_list):
                                # print(syl_word)
                                elelist=syl_word.split(' . ')
                                if len(elelist)>1:
                                    for ele in elelist:
                                        result7=re.findall('[aɛɪouœyeiøəʊɔʏɐεI]',ele)
                                        if result7==[]:
                                            if '重读音节错误' not in syl_erro:
                                                syl_erro['重读音节错误'] = [sequence+'\t'+syl_word+'\t'+ele]
                                            else:
                                                syl_erro['重读音节错误'].append(sequence+'\t'+syl_word+'\t'+ele)
                            # syllable_one_hot = get_elemento_one_hot(word_list)  # 获取单词的音节情况
                            # for index, syl_word in enumerate(syllable_one_hot):
                            #     word = word_list[index]
                            #     # print(syl_word)
                            #     syllable = get_syllable(syl_word)
                            #     # print(word,syllable)
                            #     old_sylflag = re.findall('\.', rhword_list[index])  # 旧的音节
                            #     syl_flag = re.findall('\.', syllable)  # 获取单词的音节
                            #     if len(old_sylflag) != len(syl_flag):
                            #         if '重读音节错误' not in syl_erro:
                            #             syl_erro['重读音节错误'] = [sequence+'\t'+word+'\t实际结果：'+rhword_list[index]+'\t划分结果：'+syllable]
                            #         else:
                            #             syl_erro['重读音节错误'].append(sequence+'\t'+word+'\t实际结果：'+rhword_list[index]+'\t划分结果：'+syllable)
                            #连读符号错误
                            # for j in range(len(word_list)):
                            #     if j < len(word_list) - 1:
                            #         chflag=re.findall('\w',word_list[j][-1])
                            #         if chflag!=[]: #如果最后一个字符是字母
                            #             if word_list[j][-1] in ['r', 's', 'z'] and word_list[j + 1][0] in vowel0:
                            #                 if '连读符号错误' not in recorddic4:
                            #                     recorddic4['连读符号错误']=[sequence+'\t'+word_list[j]]
                            #                 else:
                            #                     recorddic4['连读符号错误'].append(sequence+'\t'+word_list[j])
                            for index,word in enumerate(word_list):
                                rhword=rhword_list[index]
                                newword = re.sub('\W', '', word)
                                if newword not in allword_dic:
                                    allword_dic[newword]=[rhword]
                                else:
                                    if rhword not in allword_dic[newword]:
                                        allword_dic[newword].append(rhword)
                                result = re.findall('\d', rhword)  # 如果有多个重音
                                result1 = re.findall('[03456789]', rhword)  # 重音标记错误
                                result2 = re.findall('\.', rhword)  # 缺少重音符号
                                if len(result) > 1:
                                    if len(result)>2:
                                        if '多个重音符号' not in recorddic1:
                                            recorddic1['多个重音符号'] = [sequence+'\t'+rhword]
                                        else:
                                            recorddic1['多个重音符号'].append(sequence+'\t'+rhword)
                                    if ''.join(result) in ['11','22']:
                                        if '多个重音符号' not in recorddic1:
                                            recorddic1['多个重音符号'] = [sequence+'\t'+rhword]
                                        else:
                                            recorddic1['多个重音符号'].append(sequence+'\t'+rhword)
                                if result1 != []:
                                    if '重音标记错误' not in recorddic2:
                                        recorddic2['重音标记错误'] = [sequence+'\t'+rhword]
                                    else:
                                        recorddic2['重音标记错误'].append(sequence+'\t'+rhword)
                                if result2 != [] and result == []:
                                    if '缺少重读符号' not in recorddic3:
                                        recorddic3['缺少重读符号'] = [sequence+'\t'+rhword]
                                    else:
                                        recorddic3['缺少重读符号'].append(sequence+'\t'+rhword)
                                dig_result=re.findall('\s+\d',rhword)
                                if dig_result!=[]:
                                    # print(dig_result)
                                    if '重音标记前面有空白符' not in digiterro:
                                        digiterro['重音标记前面有空白符'] = [sequence+'\t'+rhword]
                                    else:
                                        digiterro['重音标记前面有空白符'].append(sequence+'\t'+rhword)
                                # elelist=re.sub('[\d\W]','',rhword).split(' ')
                                elelist = re.sub('\d', '', rhword).split(' ')
                                for ele in elelist:
                                    if ele!='.':
                                        if ele not in alleledic:
                                            alleledic[ele]=1
                                        else:
                                            alleledic[ele]+=1
                        else:
                            if '音标行与文本行长度不一致' not in fileerro:
                                fileerro['音标行与文本行长度不一致']=[sequence+'\n'+str(len(word_list))+':'+str(word_list)+'\n'+str(len(rhword_list))+':'+str(rhword_list)]
                            else:
                                fileerro['音标行与文本行长度不一致'].append(sequence+'\n'+str(len(word_list))+':'+str(word_list)+'\n'+str(len(rhword_list))+':'+str(rhword_list))
                if fileerro!={}:
                    if file not in allrecord:
                        allrecord[file]=[fileerro]
                if recorddic1!={}:
                    if file not in allrecord:
                        allrecord[file]=[recorddic1]
                    else:
                        allrecord[file] .append(recorddic1)
                if recorddic2!={}:
                    if file not in allrecord:
                        allrecord[file]=[recorddic2]
                    else:
                        allrecord[file] .append(recorddic2)
                if recorddic3!={}:
                    if file not in allrecord:
                        allrecord[file]=[recorddic3]
                    else:
                        allrecord[file] .append(recorddic3)
                if recorddic4!={}:
                    if file not in allrecord:
                        allrecord[file]=[recorddic4]
                    else:
                        allrecord[file].append(recorddic4)
                if spaceerro!={}:
                    if file not in allrecord:
                        allrecord[file]=[spaceerro]
                    else:
                        allrecord[file] .append(spaceerro)
                if recorddic5!={}:
                    if file not in allrecord:
                        allrecord[file] = [recorddic5]
                    else:
                        allrecord[file].append(recorddic5)
                if recorddic6!={}:
                    if file not in allrecord:
                        allrecord[file] = [recorddic6]
                    else:
                        allrecord[file].append(recorddic6)
                if syl_erro!={}:
                    if file not in allrecord:
                        allrecord[file] = [syl_erro]
                    else:
                        allrecord[file].append(syl_erro)
                if digiterro!={}:
                    # print(digisterro)
                    if file not in allrecord:
                        allrecord[file] = [digiterro]
                    else:
                        allrecord[file].append(digiterro)
            else:
                if file not in errodic:
                    errodic[file]=['行数不为偶数，格式为一行文本一行音标']
                else:
                    errodic[file].append('行数不为偶数，格式为一行文本一行音标')
    if errodic!={}:
        with open('行数错误.txt','w',encoding='utf-8') as w:
            for file,values in errodic.items():
                w.write('*'*20+file+'*'*20+'\n')
                w.write('\n'.join(values)+'\n')
    #所有错误类型
    if allrecord!={}:
        with open('错误记录.txt','w',encoding='utf-8') as w:
            for file,errolist in allrecord.items():
                w.write('*'*20+file+'*'*20+'\n')
                for errodic in errolist:
                    for errotype,info in errodic.items():
                        w.write('*' * 5 + errotype + '*' * 5 + '\n')
                        w.write('\n'.join(info)+'\n')
    #所有音素统计
    allelenum=0
    lackele=[i for i in legal_w if i not in alleledic]   #缺少音素
    illegal=[i for i in alleledic if i not in legal_w] #非法音素
    for ele,num in alleledic.items():
        allelenum+=num
    with open('音素统计.txt', 'w', encoding='utf-8') as w:
        w.write('音素\t出现频次\t覆盖率\n')
        for ele,num in alleledic.items():
            w.write('{}\t{}\t{:.5}%\n'.format(ele,num,num/allelenum*100))
        w.write('缺少音素:{}\n非法音素:{}\n'.format(str(lackele),str(illegal)))
    #单词出现多个读音
    if allword_dic!={}:
        with open('单词读音不一致.txt', 'w', encoding='utf-8') as w:
            for word,values in allword_dic.items():
                if len(values)>2:
                    w.write(word+'\t'+str(values)+'\n')
# path='1'
if len(sys.argv) < 2:
    print(sys.stderr, "usage: python 质检及统计音素频次.py in_path ")
    exit()
else:
    path=sys.argv[1]
    main(path)
